#goods应用下views.py

from django.core.paginator import Paginator, EmptyPage
from django.http import HttpResponseNotFound, HttpResponseForbidden, JsonResponse
from django.shortcuts import render
from django.views import View

from contents.utils import get_categories
from goods.models import GoodsCategory, SKU
from orders.models import OrderGoods
from xiaoyu_mall_new import settings
from xiaoyu_mall_new.utils.response_code import RETCODE
from .constants import PER_PRODUCTS_LIMIT as per_goods_num
from .utils import get_breadcrumb

class GoodsCommentView(View):
    """订单商品评价信息"""

    def get(self, request, sku_id):
        # 获取被评价的订单商品信息
        order_goods_list = OrderGoods.objects.filter(sku_id=sku_id, is_commented=True).order_by('-create_time')[:30]
        comment_list = []
        for order_goods in order_goods_list:
            username = order_goods.order.user.username
            comment_list.append({
                'username': username[0] + '***' + username[-1]
                if order_goods.is_anonymous else username,
                'comment': order_goods.comment,
                'score': order_goods.score,
            })
        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK',
                             'comment_list': comment_list})

#goods应用下views.py
class DetailView(View):
    """商品详情页"""

    def get(self, request, sku_id):
        """提供商品详情页"""
        # 获取当前sku的信息
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request, '404.html')
        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            key = sku_key[:]
            # 该spu商品的所有规格选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id  # 设置当前商品的规格参数
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options
        # 渲染页面
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'stock': sku.stock,
            'specs': goods_specs,
        }
        return render(request, 'detail.html', context)

#goods应用下views.py
class HostGoodsView(View):
    """热销排行"""

    def get(self, request, category_id):
        # 1 查询热销数据（结果为SKU模型类的对象列表）
        skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]
        # 2 将模型列表转字典构造JSON数据
        hot_skus = []
        for sku in skus:
            sku_dict = {
                'id': sku.id,
                'name': sku.name,
                'price': sku.price,
                # 'default_image_url': settings.STATIC_URL + 'images/goods/' + sku.default_image.url + '.jpg'
                'default_image_url': "http://localhost:8000/" + settings.STATIC_URL + 'images/goods/' + sku.default_image.url + '.jpg'
            }
            hot_skus.append(sku_dict)
        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


class ListView(View):
    def get(self, request, category_id, page_num):
        """提供商品列表页，
        category_id：商品类别id
        page_num：第几页，页号"""
        try:
            # 1 根据商品类别id获取该商品类别
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return HttpResponseNotFound('"参数category_id不存在"')

        # 2 接收sort参数，如果没有传递这个参数，那么使用默认的排序方式。分别对应html页面中的默认、人气和价格3种排序方式
        sort = request.GET.get('sort', 'default')
        # 默认排序 按价格排序 按人气排序
        if sort == 'price':
            sort_field = 'price'
        elif sort == 'hot':
            sort_field = '-sales'
        else:
            sort = 'default'
            sort_field = 'create_time'

        # 3 根据类别信息反向查询，获取商品列表
        skus = category.sku_set.filter(is_launched=True).order_by(sort_field)
        # 4 数据分页功能
        # 创建分页器
        paginator = Paginator(skus, per_goods_num)  # 对skus进行分页，每页显示5条数据
        # 获取用户当前要看的那一页数据
        try:
            page_skus = paginator.page(page_num)
        except EmptyPage:
            return HttpResponseForbidden('Empty Page')
        # 获取总的页码数，前端分页插件中需要使用
        total_page = paginator.num_pages
        # 查询商品分类
        categories = get_categories()
        # 5 查询面包屑导航：一级 ==>二级==>一级
        breadcrumb = get_breadcrumb(category)

        # 6 根据商品类别id，查询所有的在售商品
        skus = SKU.objects.filter(category_id=category_id, is_launched=True)
        # 把所有商品的sku id 存放在sku_li中
        sku_li = []  # 保存当前页所有的sku_id
        for sku in skus:
            sku_li.append(sku.id)
        # 7 获取每个sku-id的评论数量
        product_review_num = []
        for sid in sku_li:
            # 根据商品id获取已评论的订单
            order_goods_list = OrderGoods.objects.filter(sku_id=sid, is_commented=True)
            # 保存每件商品的评价内容
            product_review_content = []
            for order_goods in order_goods_list:
                product_review_content.append(order_goods.comment)
            product_review_num.append(len(product_review_content))
        # 获取每页各个商品的评价数量,并保存到列表中
        per_review_num = [product_review_num[i:i + per_goods_num] for i in
                          range(0, len(product_review_num), per_goods_num)]
        # 获取当前访问各个商品的数量
        cur_per_review_num = per_review_num[page_skus.number - 1]
        # 8 将每个商品数量赋值给每个商品sku对象
        # 通过zip函数将sku对象和评价数量进行组合，格式为：[(sku对象,商品评价数量)]
        for sku in list(zip(page_skus, cur_per_review_num)):
            # 动态添加商品评价数量review_num属性
            sku[0].review_num = sku[1]

        context = {
            'category_id': category_id,
            'sort': sort,
            'page_skus': page_skus,
            'page_num': page_num,
            'total_page': total_page,
            'categories': categories,
            'breadcrumb': breadcrumb,
        }

        print(context)
        return render(request, 'list.html', context)
